/*
 * 创建日期 2005-8-29
 *
 * 更改所生成文件模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
package com.vanda.report.cfg;

import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import net.sf.hibernate.MappingException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.vanda.report.ReportException;
import com.vanda.report.element.ReportElement;
import com.vanda.util.Globals;
import com.vanda.util.LogFunc;

/**
 * @author wkf5985
 *
 * 更改所生成类型注释的模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
public class Configuration {
	private static Log log = LogFactory.getLog(Configuration.class);

	private static final String REPORT_CONFIG_DIR = "report_relative_dir";
	private static final String REPORT_MODEL_DIR = "model_relative_dir";
	private static final String SYSTEM_REPORT_DIR = "com.vanda.system.report.config";
	public static final String SYSTEM_REPORT_OUTDIR = "com.vanda.system.report.output";
	
	public static URI modelURI = null;
	
	/**
	 * 解析配置文件
	 * @param resourceURL 主配置文件路径
	 * @return
	 * @throws Exception
	 */
	public void configure() throws Exception {
		// 需要读取配置信息
		String resourceURL = Globals.getValue(SYSTEM_REPORT_DIR);
		
		HashMap hmReport = new HashMap();
		//Property集合
		HashMap hmProperty = new HashMap();
		//validator集合
		HashMap hmValidator = new HashMap();
		ReportCfgBean cfgBean = ReportCfgBean.getInstance();

		
		//取得主配置文件流
		InputStream stream = getResource(resourceURL);

		//解析xml文件
		SAXReader saxReader = new SAXReader();
		Document document = saxReader.read(stream);
		//读取Property属性
		List list =
			document.selectNodes(
				"/report-configuration/report-factory/property");
		Iterator iter = list.iterator();
		iter = list.iterator();
		while (iter.hasNext()) {
			Element property = (Element) iter.next();
			String name = getAttribute(property, "name", true);
			String value = getElement(property, true);
			hmProperty.put(name, value);
		}
		LogFunc.info("Read property success!");
		//取得relative_dir和sqlconfig_relative_dir
		String reportDir =
			(String) hmProperty.get(REPORT_CONFIG_DIR);
		String modelDir =
			(String) hmProperty.get(REPORT_MODEL_DIR);
		URI reportURI = null;
		
		//生成report目录路径
		if (reportDir != null) {
			reportURI = new URI(reportDir);
			log.debug("reportURI = " + reportURI);
		}
		//生成model目录路径
		if (modelDir != null) {
			modelURI = new URI(modelDir);
			log.debug("modelURI = " + modelURI);
		}
		//读取Mapping文件
		list =
			document.selectNodes(
				"/report-configuration/report-factory/report");
		iter = list.iterator();
		while (iter.hasNext()) {
			Element mapping = (Element) iter.next();
			String resource = getAttribute(mapping, "resource", true);
			LogFunc.info("Reading mapping file[" + resource + "]...");
			List elements = ReportParse.parseXML(resource, reportURI);
			for (int i = 0; i < elements.size(); i++) {
				ReportElement element = (ReportElement) elements.get(i);
				hmReport.put(element.getId(), element);
			}
			LogFunc.info("Read mapping file[" + resource + "] success!");
		}
		
		//读取Validator
		list = document.selectNodes("/report-configuration/report-factory/validator");
		iter = list.iterator();
		while(iter.hasNext()){
			Element validator = (Element) iter.next();
			
			ValidatorBean vBean = new ValidatorBean();
			String name = getAttribute(validator, "name", true);
			String clsName = getAttribute(validator, "className", true);
			String method = getAttribute(validator, "method", true);
			String msg = getAttribute(validator, "msg", true);
			
			vBean.setName(name);
			vBean.setClassName(clsName);
			vBean.setMethod(method);
			vBean.setMsg(msg);
			
			hmValidator.put(name,vBean);
		}
		
		cfgBean.setPropertys(hmProperty);
		cfgBean.setReports(hmReport);
		cfgBean.setValidator(hmValidator);
	}
	/**
	 * 取得resourceURL的文件流
	 * @param resourceURL
	 * @return
	 * @throws Exception
	 */
	private InputStream getResource(String resourceURL) throws Exception {
		InputStream stream = Configuration.class.getResourceAsStream(resourceURL);

		if (stream == null) {
			stream = new FileInputStream(resourceURL);
		}
		if (stream == null) {
			log.error(resourceURL + " not found");
			throw new ReportException(resourceURL + " not found");
		}
		return stream;
	}
	


	/**
	 * 取得元素的属性值
	 * @param element 元素
	 * @param name 属性名
	 * @param nullCheck 空校验，true-校验，false-不校验
	 * @return
	 * @throws MappingException
	 */
	private String getAttribute(
		Element element,
		String name,
		boolean nullCheck)
		throws MappingException {
		String value = element.attributeValue(name);
		if (nullCheck) {
			if (value == null || value.trim().equals("")) {
				log.error(
					element.getName() + "->" + name + ": must not be null!");
				throw new MappingException(
					element.getName() + "->" + name + ": must not be null!");
			}
		}
		return value;
	}
	/**
	 * 取得元素值
	 * @param element 元素
	 * @param nullCheck 空校验，true-校验，false-不校验
	 * @return
	 * @throws MappingException
	 */
	private String getElement(Element element, boolean nullCheck)
		throws MappingException {
		String value = element.getText();
		if (nullCheck) {
			if (value == null || value.trim().equals("")) {
				log.error(element.getName() + ": must not be null!");
				throw new MappingException(
					element.getName() + ": must not be null!");
			}
		}
		return value;
	}

}
